<?php
/**
 *+------------------
 * Lflow
 *+------------------
 * Copyright (c) 2023~2030 gitee.com/liu_guan_qing All rights reserved.本版权不可删除，侵权必究
 *+------------------
 * Author: Mr.April(405784684@qq.com)
 *+------------------
 */
declare (strict_types=1);

namespace lflow\workflow;

use lflow\access\AbstractDBAccess;
use lflow\access\dialect\Dialect;
use lflow\access\Page;
use lflow\access\QueryFilter;
use lflow\entity\HistoryOrder;
use lflow\entity\HistoryTask;
use lflow\entity\Order;
use lflow\entity\Task;
use lflow\helper\AssertHelper;
use lflow\helper\StringHelper;
use lflow\IQueryService;
use lflow\WorkFlowException;
use ReflectionClass;

/**
 * 查询服务类
 *
 * @author Mr.April
 * @since  1.0
 */
class QueryService extends AccessService implements IQueryService
{

    public function getOrder(string $orderId): ?Order
    {
        return $this->access()->getOrder($orderId);
    }

    public function getTask(string $taskId): ?Task
    {
        return $this->access()->getTask($taskId);
    }

    public function getTaskActorsByTaskId(string $taskId): array
    {
        $actors = $this->access()->getTaskActorsByTaskId($taskId);
        if (empty($actors)) {
            return [];
        }
        return array_column($actors, 'actor_id');
    }

    public function getHistoryTaskActorsByTaskId(string $taskId): array
    {
        $actors = $this->access()->getHistTaskActorsByTaskId($taskId);
        if (empty($actors)) {
            return [];
        }
        return array_column($actors, 'actor_id');
    }

    public function getHistOrder(string $orderId): ?HistoryOrder
    {
        return $this->access()->getHistOrder($orderId);
    }

    public function getHistOrders(string $orderId): ?HistoryOrder
    {
        AssertHelper::notNull($orderId);
        $sql = "select o.id,o.process_id,o.order_state,o.priority,o.creator,o.create_time,o.end_time,o.parent_id,o.expire_time,o.order_no,o.variable,p.display_name as process_name from wf_hist_order o ";
        $sql .= " left join wf_process p on p.id = o.process_id ";
        $sql .= " where 1=1 ";
        $sql .= " and o.id = ? ";
        return $this->nativeQueryObject(HistoryOrder::class, $sql, [$orderId]);
    }

    public function getHistTask(string $taskId): ?HistoryTask
    {
        return $this->access()->getHistTask($taskId);
    }

    public function getActiveTasks(QueryFilter $filter, Page|null $page = null): array
    {
        AssertHelper::notNull($filter);
        return $this->access()->getActiveTasks($filter, $page);
    }

    public function getActiveOrders(QueryFilter $filter, Page|null $page = null): array
    {
        AssertHelper::notNull($filter);
        return $this->access()->getActiveOrders($filter, $page);
    }

    public function getHistoryOrders(QueryFilter $filter, Page|null $page = null): array
    {
        AssertHelper::notNull($filter);
        return $this->access()->getHistoryOrders($filter, $page);
    }

    public function getHistoryTasks(QueryFilter $filter, Page|null $page = null): array
    {
        AssertHelper::notNull($filter);
        return $this->access()->getHistoryTasks($filter, $page);
    }

    public function getWorkItems(QueryFilter $filter, Page|null $page = null): array
    {
        AssertHelper::notNull($filter);
        return $this->access()->getWorkItems($filter, $page);
    }

    public function getCCWorks(QueryFilter $filter, Page|null $page = null): array
    {
        AssertHelper::notNull($filter);
        return $this->access()->getCCWorks($filter, $page);
    }

    public function getHistoryWorkItems(QueryFilter $filter, Page|null $page = null): array
    {
        AssertHelper::notNull($filter);
        return $this->access()->getHistoryWorkItems($filter, $page);
    }

    public function nativeQueryObject(string $clazz, string $sql, array $args): ?object
    {
//        AssertHelper::notEmpty($clazz);
        AssertHelper::notNull($sql);
        return $this->access()->queryObject($clazz, $sql, $args);
    }

    public function nativeQueryList(string $clazz, string $sql, array $args): array
    {
        AssertHelper:: notEmpty($sql);
        return $this->access()->queryList($clazz, $sql, $args);
    }

    public function nativeQueryCount(string $clazz, string $sql, array $args, Page $page): array
    {
        AssertHelper:: notEmpty($sql);
        AssertHelper:: notEmpty($page);
        return $this->access()->queryList($clazz, $sql, $args);
    }

    public function queryCount($sql, $args): int
    {
        return $this->access()->queryCount($sql, $args);
    }

    /**
     * sql 方言
     *
     * @return mixed
     */
    public function dialect(): Dialect
    {
        return $this->access()->dialect();
    }
    //    public function get(string $id): array
//    {
//        $field    = "o.process_id, t.order_id, t.id as id, t.id as task_id, p.display_name as process_name, p.instance_url, o.parent_id, o.creator,  o.create_time as order_create_time, o.expire_time as order_expire_time, o.order_no, o.variable as order_variable,  t.display_name as task_name, t.task_name as task_key, t.task_type, t.perform_type, t.operator, t.action_url,  t.create_time as task_create_time, t.finish_time as task_end_time, t.expire_time as task_expire_time, t.variable as task_variable";
//        $workItme = (new Task())
//            ->alias('t')
//            ->field($field)
//            ->join('wf_order o', 't.order_id = o.id')
//            ->join('wf_task_actor ta', 'ta.task_id=t.id')
//            ->join('wf_process p', 'p.id = o.process_id')
//            ->where('t.id', $id)
//            ->find();
//        if ($workItme === null) {
//            $workItme = (new HistoryTask())
//                ->alias('t')
//                ->field($field)
//                ->join('wf_hist_order o', 't.order_id = o.id')
//                ->join('wf_hist_task_actor ta', 'ta.task_id=t.id')
//                ->join('wf_process p', 'p.id = o.process_id')
//                ->where('t.id', $id)
//                ->find();
//        }
//        if ($workItme == null) {
//            throw new Exception('任务不存或被删除');
//        }
//        $data                     = $workItme->toArray();
//        $data['orderVariableMap'] = json_decode($data['orderVariable'], 1) ?? [];
//        $data['taskVariableMap']  = json_decode($data['taskVariable'], 1) ?? [];
//        return $data;
//    }
}
